<template>
  <div class="com-container">
    <div ref="histogram_ref" class="com-chart" />
  </div>
</template>

<script>
import { getFullTag } from '@/api/common/common'

export default {
  name: 'HistogramChart',
  props: {
    title: {
      type: String,
      default: '标题'
    },
    url: {
      type: String,
      default: ''
    },
    unit: {
      type: String,
      default: '个'
    }
  },
  data() {
    return {
      typeList: [],
      data: [],
      chartInstance: null
    }
  },
  mounted() {
    this.initChart()
    this.getData()
    window.addEventListener('resize', this.screenAdapter)
    this.screenAdapter()
  },
  methods: {
    screenAdapter() {
      this.chartInstance.resize()
    },
    initChart() {
      this.chartInstance = this.$echarts.init(this.$refs.histogram_ref, this.theme)
      // 网络请求 假装从后端拿回来的数据
      this.data = [
        { name: '京哈高速', value: 10 },
        { name: '京哈高速1', value: 20 },
        { name: '京哈高速2', value: 30 },
        { name: '京哈高速3', value: 40 },
        { name: '京哈高速4', value: 50 },
        { name: '京哈高速5', value: 60 },
        { name: '京哈高速6', value: 70 },
        { name: '京哈高速7', value: 80 },
        { name: '京哈高速8', value: 90 },
        { name: '京哈高速9', value: 100 },
        { name: '京哈高速10', value: 110 },
        { name: '京哈高速11', value: 120 }
      ]
      const xAxisText = []
      const dataList = []
      // 拼轴显示和数据的数组
      this.data.forEach(item => {
        xAxisText.push(item.name)
        dataList.push(item.value)
      })
      this.resetRect(xAxisText)
      const initOption = {
        color: ['#33b56a', '#fdcf5c', '#4c90ff', '#fe7b7a', '#69ccf6', '#a38bf8', '#ff9561', '#8cb0ea', '#fe81b4', '#ffb258'],
        title: {
          text: this.title
        },
        legend: {
          show: true,
          top: 5
        },
        grid: {
          left: '2%',
          right: '6%',
          top: '10%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          data: xAxisText,
          boundaryGap: true,
          interval: 0,
          axisLabel: {
            color: '#333',
            fontSize: 12,
            //  让x轴文字方向为竖向
            rotate: -50,
            interval: 0
          }
        },
        yAxis: {
          type: 'value'
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        series: [{
          name: '单位:' + this.unit,
          type: 'custom',
          renderItem: (params, api) => {
            const location = api.coord([api.value(0), api.value(1)])
            return {
              type: 'group',
              children: [{
                type: 'MyCubeRect',
                shape: {
                  api,
                  xValue: api.value(0),
                  yValue: api.value(1),
                  x: location[0],
                  y: location[1]
                },
                style: api.style() // api.style()——继承原本的样式
              }, {
                type: 'MyCubeShadow',
                shape: {
                  api,
                  xValue: api.value(0),
                  yValue: api.value(1),
                  x: location[0],
                  y: location[1]
                },
                style: {
                  fill: api.style(),
                  text: '' // 继承原本样式的基础上将label清空 如果不清空生成的图上会显示两个重叠的label
                }
              }]
            }
          },
          label: {
            show: true,
            position: 'top',
            color: '#333',
            formatter: '{c}' + this.unit,
            fontSize: 16,
            distance: 15
          },
          itemStyle: {
            normal: {
              color: (params) => {
                // 使每根柱子颜色都不一样
                const colorList = ['#33b56a', '#fdcf5c', '#4c90ff', '#fe7b7a', '#69ccf6', '#a38bf8', '#ff9561', '#8cb0ea', '#fe81b4', '#ffb258']
                if (params.dataIndex + 1 <= colorList.length) {
                  return colorList[params.dataIndex]
                } else {
                  // 如果柱子的数量超过颜色数组 就从头再来一遍
                  return colorList[params.dataIndex - colorList.length]
                }
              }
            }
          },
          data: dataList
        }]
      }
      this.chartInstance.setOption(initOption)
    },
    resetRect(xAxisText) {
      // 从这里开始 创建自定义图形 —— 长方体的正面
      var MyCubeRect = this.$echarts.graphic.extendShape({
        shape: {
          x: 0,
          y: 0,
          width: 180, // 长方体宽度
          zWidth: 8, // 阴影折角宽
          zHeight: 4 // 阴影折角高
        },
        buildPath: function(ctx, shape) {
          const api = shape.api
          const xAxisPoint = api.coord([shape.xValue, 0])
          const p0 = [shape.x, shape.y]
          const p1 = [shape.x - shape.width / xAxisText.length, shape.y]
          const p4 = [shape.x + shape.width / xAxisText.length, shape.y]
          const p2 = [xAxisPoint[0] - shape.width / xAxisText.length, xAxisPoint[1]]
          const p3 = [xAxisPoint[0] + shape.width / xAxisText.length, xAxisPoint[1]]

          ctx.moveTo(p0[0], p0[1]) // 0
          ctx.lineTo(p1[0], p1[1]) // 1
          ctx.lineTo(p2[0], p2[1]) // 2
          ctx.lineTo(p3[0], p3[1]) // 3
          ctx.lineTo(p4[0], p4[1]) // 4
          ctx.lineTo(p0[0], p0[1]) // 0
          ctx.closePath()
        }
      })

      // 创建第二个自定义图形 —— 长方体的上面和侧面
      var MyCubeShadow = this.$echarts.graphic.extendShape({
        shape: {
          x: 0,
          y: 0,
          width: 180,
          zWidth: 8,
          zHeight: 4
        },
        buildPath: function(ctx, shape) {
          const api = shape.api
          const xAxisPoint = api.coord([shape.xValue, 0])
          const p1 = [shape.x - shape.width / xAxisText.length, shape.y]
          const p4 = [shape.x + shape.width / xAxisText.length, shape.y]
          const p6 = [shape.x + shape.width / xAxisText.length + shape.zWidth, shape.y - shape.zHeight]
          const p7 = [shape.x - shape.width / xAxisText.length + shape.zWidth, shape.y - shape.zHeight]
          const p3 = [xAxisPoint[0] + shape.width / xAxisText.length, xAxisPoint[1]]
          const p5 = [xAxisPoint[0] + shape.width / xAxisText.length + shape.zWidth, xAxisPoint[1] - shape.zHeight]

          ctx.moveTo(p4[0], p4[1]) // 4
          ctx.lineTo(p3[0], p3[1]) // 3
          ctx.lineTo(p5[0], p5[1]) // 5
          ctx.lineTo(p6[0], p6[1]) // 6
          ctx.lineTo(p4[0], p4[1]) // 4

          ctx.moveTo(p4[0], p4[1]) // 4
          ctx.lineTo(p6[0], p6[1]) // 6
          ctx.lineTo(p7[0], p7[1]) // 7
          ctx.lineTo(p1[0], p1[1]) // 1
          ctx.lineTo(p4[0], p4[1]) // 4
          ctx.closePath()
        }
      })
      this.$echarts.graphic.registerShape('MyCubeRect', MyCubeRect)
      this.$echarts.graphic.registerShape('MyCubeShadow', MyCubeShadow)
    },
    async getData() {
      if (this.url !== '') {
        await getFullTag(this.url).then(response => {
          this.data = response.map(item => {
            return { name: item['name'], value: item['total'] }
          })
        })
        const xAxisText = this.data.map(item => item['name'])
        const dataOption = {
          xAxis: {
            data: xAxisText
          },
          series: [{
            data: this.data.map(item => item['value'])
          }]
        }
        this.resetRect(xAxisText)
        await this.chartInstance.setOption(dataOption)
      }
    }
  }
}
</script>

<style scoped>
  .com-container {
    width: 100%;
    height: 350px;
    overflow: hidden;
  }

  .com-chart {
    width: 100%;
    height: 100%;
    overflow: hidden;
  }

  canvas {
    border-radius: 0;
  }
</style>
